<?php
/*
 * @Author: CHINAKAIYUAN<sunkaiyuan@namenode.cn>
 * @Date: 2022-02-03 01:21:39
 * @LastEditTime: 2023-10-14 15:24:51
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @Description: 
 * 汇总明细账 -> belongsto汇总库存，source源表，hasMany批次库存账
 * 汇总库存 -> hasMany汇总明细账
 * 批次库存账 -> belongsto批次库存，belongsto汇总明细账
 
 * 创建库存  
 *  1、创建批次库存，2、创建汇总库存账，3、创建批次库存账，保存汇总库存账ID，批次库存Id，4、计算汇总库存
 *  5、单据，保存汇总库存账ID   
 * 
 * 库存操作通过  批次库存-》汇总库存账->批次库存账-》批次库存->更新汇总库存
 */

namespace App\Traits;

use App\Models\Company;
use App\Models\Material;
use App\Models\Middle;
use App\Models\MpcLocation;
use App\Models\MpcLot;
use App\Models\MpcSummaryDetail;
use Illuminate\Support\Facades\App;
use App\Repositories\StorageRepository;
use Illuminate\Database\Eloquent\Collection;


//Model Trait

trait StorageTrait
    {
    use MaterialTrait;
    protected $_storageRepository = null;

    public function getPaperCode()
        {
        fail("未找到对应code!,库存明细账必要字段！");
        }
    /**
     * 返回批次库存保存值
     * @return array
     * @author sunkaiyuan
     */
    public function getStorageMergeData()
        {
        return [];
        }
    //指定批次库存，返回null，不指定批次，按从大到小扣数/入库
    /**
     * 指定批次库存，返回null，不指定批次，按从大到小扣数/入库
     * @return null|Collection
     * @author sunkaiyuan
     */
    public function getBatchStorage()
        {
        return null;
        }
    public function getStorageRepository()
        {
        return $this->_storageRepository == null ? $this->_storageRepository = App::make(StorageRepository::class) : $this->_storageRepository;
        }
    public function mergeWhere($where)
        {
        $this->getStorageRepository()->mergeWhere($where);
        return $this;
        }
    public function scopeMergeWhere($query, $where)
        {
        $this->getStorageRepository()->mergeWhere($where);
        return $this;
        }
    public function scopeAddStorage(
        $query,
        $name = '',
        $code = '',
        $quantity = 0,
        $auxiliary_quantity = 0,
        $saveMiddleIdFieldName = "mpc_detail",
        $sourcekey = 'id',
    ) {
        return $query->get()->filter(function ($model) use ($quantity, $auxiliary_quantity, $name, $code, $saveMiddleIdFieldName, $sourcekey)
            {
            return $this->addStorage(
                $name,
                $code,
                $quantity == 0 ? $model->quantity : $quantity,
                $auxiliary_quantity == 0 ? $model->auxiliary_quantity : $auxiliary_quantity,
                $saveMiddleIdFieldName,
                $sourcekey,
                $model
            );
            });
        }
    public function mpc_detail()
        {
        return $this->belongsTo(MpcSummaryDetail::class);
        }
    public function old_mpc_detail()
        {
        return $this->belongsTo(MpcSummaryDetail::class);
        }
    public function addStorage(
        $name = '',
        $code = '',
        $quantity = 0,
        $auxiliary_quantity = 0,
        $saveMiddleIdFieldName = "mpc_detail",
        $sourcekey = 'id',
        $model = null
    ) {
        $model    = $model == null ? $this : $model;
        $quantity = $quantity ?? $model->quantity ?? 0;

        return $this->getStorageRepository()->add(
            $model,
            $quantity,
            $auxiliary_quantity,
            $name,
            $code,
            $saveMiddleIdFieldName,
            $sourcekey
        );
        }
    public function scopeUseStorage(
        $query,
        $name = '',
        $code = '',
        $quantity = 0,
        $auxiliary_quantity = 0,
        $saveMiddleIdFieldName = "mpc_detail",
        $sourcekey = 'id'
    ) {

        return $query->get()->filter(function ($model) use ($quantity, $auxiliary_quantity, $saveMiddleIdFieldName, $name, $code, $sourcekey)
            {
            return $this->useStorage(
                $name,
                $code,
                $quantity,
                $auxiliary_quantity,
                $saveMiddleIdFieldName,
                $sourcekey,
                $model
            );
            });
        }

    public function setWhere($where, $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->setWhere($where, $model);
        }

    public function scopeSetWhere($query, $where)
        {
        return $query->get()->filter(function ($model) use ($where)
            {
            return $this->setWhere($where, $model);
            });
        }
    public function setOutSoucing($flag = true, $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->setOutSoucing($flag, $model);
        }
    public function scopesetOutSoucing($query, $flag = true)
        {
        return $query->get()->filter(function ($model) use ($flag)
            {
            return $this->setOutSoucing($flag, $model);
            });
        }
    public function useStorage(
        $name = '',
        $code = '',
        $quantity = null,
        $auxiliary_quantity = null,
        $saveMiddleIdFieldName = "mpc_detail",
        $sourcekey = 'id',
        $model = null
    ) {
        $model              = $model == null ? $this : $model;
        $quantity           = $quantity ?? ($model->quantity ?? 0);
        $auxiliary_quantity = $auxiliary_quantity ?? ($model->auxiliary_quantity ?? 0);
        return $this->getStorageRepository()->use(
            $model,
            $quantity,
            $auxiliary_quantity,
            $saveMiddleIdFieldName,
            $name,
            $code,
            $sourcekey
        );
        }
    //设置数量和包数
    private function _setComputeQuantity($quantity, $model)
        {
        // moisture 
        $auxiliary_quantity = 0;

        return $auxiliary_quantity;
        }
    public function scopeSubStorage($query, $saveMiddleRelationName = "mpc_detail")
        {
        return $query->get()->filter(function ($model) use ($saveMiddleRelationName)
            {
            return $this->subStorage($saveMiddleRelationName, $model);
            });
        }
    public function subStorage($saveMiddleRelationName = "mpc_detail", $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->sub($model, $saveMiddleRelationName);
        }


    public function scopeNoaddStorage($query, $saveMiddleIdFieldName = "mpc_detail")
        {
        return $query->get()->filter(function ($model) use ($saveMiddleIdFieldName)
            {
            return $this->noaddStorage($saveMiddleIdFieldName, $model);
            });
        }
    public function noaddStorage($saveMiddleIdFieldName = "mpc_detail", $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->noadd($model, $saveMiddleIdFieldName);
        }

    public function scopeNouseStorage($query, $saveMiddleRelationName = "mpc_detail")
        {
        return $query->get()->filter(function ($model) use ($saveMiddleRelationName)
            {
            return $this->nouseStorage($saveMiddleRelationName, $model);
            });
        }
    public function nouseStorage($saveMiddleRelationName = "mpc_detail", $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->nouse($model, $saveMiddleRelationName);
        }


    public function scopeNosubStorage($query, $saveMiddleRelationName = "mpc_detail")
        {
        return $query->get()->filter(function ($model) use ($saveMiddleRelationName)
            {
            return $this->nosubStorage($saveMiddleRelationName, $model);
            });
        }
    public function isSub($saveMiddleRelationName = "mpc_detail")
        {
        return $this->{$saveMiddleRelationName}?->out_quantity ?? 0 > 0;
        }
    public function isUse($saveMiddleRelationName = "mpc_detail")
        {
        return $this->{$saveMiddleRelationName}?->occupy_quantity ?? 0 > 0;
        }
    public function nosubStorage($saveMiddleRelationName = "mpc_detail", $model = null)
        {
        $model = $model == null ? $this : $model;
        return $this->getStorageRepository()->nosub($model, $saveMiddleRelationName);
        }
    }